home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / MacHacksBug / Python 1.5.2c1 / Demo / zlib / minigzip.py next >
Encoding:
Python Source  |  2000-06-23  |  3.7 KB  |  108 lines

  1. #!/usr/bin/env python
  2. # Demo program for zlib; it compresses or decompresses files, but *doesn't*
  3. # delete the original.  This doesn't support all of gzip's options.
  4.  
  5. FTEXT, FHCRC, FEXTRA, FNAME, FCOMMENT = 1, 2, 4, 8, 16
  6.  
  7. def write32(output, value):
  8.     output.write(chr(value & 255)) ; value=value / 256
  9.     output.write(chr(value & 255)) ; value=value / 256
  10.     output.write(chr(value & 255)) ; value=value / 256
  11.     output.write(chr(value & 255))
  12.     
  13. def read32(input):
  14.     v=ord(input.read(1))
  15.     v=v+ (ord(input.read(1))<<8 )
  16.     v=v+ (ord(input.read(1))<<16)
  17.     v=v+ (ord(input.read(1))<<24)
  18.     return v
  19.  
  20. import zlib, sys
  21. if len(sys.argv)!=2:
  22.    print 'Usage: minigzip.py <filename>'
  23.    print '  The file will be compressed or decompressed.'
  24.    sys.exit(0)
  25.  
  26. filename=sys.argv[1]
  27. compressing=1 ; outputname=filename+'.gz'
  28. if filename[-3:]=='.gz':
  29.     compressing=0 ; outputname=filename[:-3]
  30. input=open(filename) ; output=open(outputname, 'w')
  31.  
  32. if compressing:
  33.     output.write('\037\213\010')        # Write the header, ...
  34.     output.write(chr(FNAME))            # ... flag byte ...
  35.  
  36.     import os                           # ... modification time ...
  37.     statval=os.stat(filename)
  38.     mtime=statval[8]
  39.     write32(output, mtime)
  40.     output.write('\002')                # ... slowest compression alg. ...
  41.     output.write('\377')                # ... OS (=unknown) ...
  42.     output.write(filename+'\000')       # ... original filename ...
  43.  
  44.     crcval=zlib.crc32("")
  45.     compobj=zlib.compressobj(9, zlib.DEFLATED, -zlib.MAX_WBITS,
  46.                              zlib.DEF_MEM_LEVEL, 0)
  47.     while (1):
  48.         data=input.read(1024)
  49.         if data=="": break
  50.         crcval=zlib.crc32(data, crcval)
  51.         output.write(compobj.compress(data))
  52.     output.write(compobj.flush())
  53.     write32(output, crcval)             # ... the CRC ...
  54.     write32(output, statval[6])         # and the file size.
  55.  
  56. else:
  57.     magic=input.read(2)
  58.     if magic!='\037\213':
  59.         print 'Not a gzipped file' ; sys.exit(0)
  60.     if ord(input.read(1))!=8:
  61.         print 'Unknown compression method' ; sys.exit(0)
  62.     flag=ord(input.read(1))
  63.     input.read(4+1+1)                   # Discard modification time,
  64.                                         # extra flags, and OS byte.
  65.     if flag & FEXTRA:
  66.         # Read & discard the extra field, if present
  67.         xlen=ord(input.read(1))         
  68.         xlen=xlen+256*ord(input.read(1))
  69.         input.read(xlen)
  70.     if flag & FNAME:
  71.         # Read and discard a null-terminated string containing the filename
  72.         while (1):
  73.             s=input.read(1)
  74.             if s=='\000': break
  75.     if flag & FCOMMENT:
  76.         # Read and discard a null-terminated string containing a comment
  77.         while (1):
  78.             s=input.read(1)
  79.             if s=='\000': break
  80.     if flag & FHCRC:
  81.         input.read(2)                   # Read & discard the 16-bit header CRC
  82.     decompobj=zlib.decompressobj(-zlib.MAX_WBITS)
  83.     crcval=zlib.crc32("")
  84.     length=0
  85.     while (1):
  86.         data=input.read(1024)
  87.         if data=="": break
  88.         decompdata=decompobj.decompress(data)
  89.         print len(decompdata)
  90.         output.write(decompdata) ; length=length+len(decompdata)
  91.         crcval=zlib.crc32(decompdata, crcval)
  92.     decompdata=decompobj.flush()
  93.     output.write(decompdata) ; length=length+len(decompdata)
  94.     crcval=zlib.crc32(decompdata, crcval)
  95.     
  96.     # We've read to the end of the file, so we have to rewind in order
  97.     # to reread the 8 bytes containing the CRC and the file size.  The
  98.     # decompressor is smart and knows when to stop, so feeding it
  99.     # extra data is harmless.  
  100.     input.seek(-8, 2)
  101.     crc32=read32(input)
  102.     isize=read32(input)
  103.     if crc32!=crcval: print 'CRC check failed.'
  104.     if isize!=length: print 'Incorrect length of data produced'
  105.  
  106. input.close() ; output.close()
  107.  
  108.